package token.common.util;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;

import org.joda.time.DateTime;
import token.common.pojo.UserInfo;


import java.security.*;

public class JwtUtil {
    public static final String JWT_KEY_ID = "id";
    public static final String JWT_KEY_USER_NAME = "username";
    /**
     * 私钥加密token
     *
     * @param userInfo      载荷中的数据
     * @param privateKey    私钥
     * @param expireMinutes 过期时间，单位秒
     * @return
     * @throws Exception
     */
    public static String generateToken(UserInfo userInfo, PrivateKey privateKey, int expireMinutes) throws Exception {
        return Jwts.builder()
                .claim(JWT_KEY_ID, userInfo.getId())
                .claim(JWT_KEY_USER_NAME, userInfo.getUsername())
                .setExpiration(DateTime.now().plusMinutes(expireMinutes).toDate())
                .signWith(SignatureAlgorithm.RS256, privateKey)
                .compact();
    }

    /**
     * 私钥加密token
     *
     * @param userInfo      载荷中的数据
     * @param privateKey    私钥字节数组
     * @param expireMinutes 过期时间，单位秒
     * @return
     * @throws Exception
     */
    public static String generateToken(UserInfo userInfo, byte[] privateKey, int expireMinutes) throws Exception {
        return Jwts.builder()
                .claim(JWT_KEY_ID, userInfo.getId())
                .claim(JWT_KEY_USER_NAME, userInfo.getUsername())
                .setExpiration(DateTime.now().plusMinutes(expireMinutes).toDate())
                .signWith(SignatureAlgorithm.RS256, RsaUtil.getPrivateKey(privateKey))
                .compact();
    }

    /**
     * 公钥解析token
     *
     * @param token     用户请求中的token
     * @param publicKey 公钥
     * @return
     * @throws Exception
     */
    private static Jws<Claims> parserToken(String token, PublicKey publicKey) {
        return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);
    }

    /**
     * 公钥解析token
     *
     * @param token     用户请求中的token
     * @param publicKey 公钥字节数组
     * @return
     * @throws Exception
     */
    private static Jws<Claims> parserToken(String token, byte[] publicKey) throws Exception {
        return Jwts.parser().setSigningKey(RsaUtil.getPublicKey(publicKey))
                .parseClaimsJws(token);
    }

    /**
     * 获取token中的用户信息
     *
     * @param token     用户请求中的令牌
     * @param publicKey 公钥
     * @return 用户信息
     * @throws Exception
     */
    public static UserInfo getInfoFromToken(String token, PublicKey publicKey) throws Exception {
        Jws<Claims> claimsJws = parserToken(token, publicKey);
        Claims body = claimsJws.getBody();
        UserInfo userInfo=new UserInfo();
        userInfo.setId(ObjectUtils.toLong(body.get(JWT_KEY_ID)));
        userInfo.setUsername(ObjectUtils.toString(body.get(JWT_KEY_USER_NAME)));
        return userInfo;
    }



    /**
     * 获取token中的用户信息
     *
     * @param token     用户请求中的令牌
     * @param publicKey 公钥
     * @return 用户信息
     * @throws Exception
     */
    public static UserInfo getInfoFromToken(String token, byte[] publicKey) throws Exception {
        Jws<Claims> claimsJws = parserToken(token, publicKey);
        Claims body = claimsJws.getBody();
        UserInfo userInfo=new UserInfo();
        userInfo.setId(ObjectUtils.toLong(body.get(JWT_KEY_ID)));
        userInfo.setUsername(ObjectUtils.toString(body.get(JWT_KEY_USER_NAME)));
        return userInfo;
    }

    public static void main(String[] args) throws Exception{
        /**RsaUtil.generateKey("D:\\los\\rsarsa.pub","D:\\los\\rsa.pri","opop");
        PublicKey publicKey=RsaUtil.getPublicKey("D:\\los\\rsarsa.pub");
        PrivateKey privateKey=RsaUtil.getPrivateKey("D:\\los\\rsa.pri");
        UserInfo userInfo=new UserInfo();
        userInfo.setId(9L);
        userInfo.setUsername("lp");
        String token=generateToken(userInfo,privateKey,30);
        UserInfo u=getInfoFromToken(token,publicKey);
        System.out.println(u);
         */
       /**File directory = new File("emall-token/token-common/src/main/resources/a.txt");
        String reportPath = directory.getCanonicalPath();
        File file=new File(reportPath);
        FileInputStream fileOutputStream=new FileInputStream(file);
        BufferedReader bufferedReader=new BufferedReader(new ReaderUTF8(fileOutputStream));
        String string = "";
        while((string=bufferedReader.readLine())!=null){
            System.out.println(string);
        }


        System.out.println(reportPath);

        */

    }
}
